home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / sound / rsynth22.zip / AUFILE.C < prev    next >
Text File  |  1996-09-13  |  7KB  |  323 lines

  1. #include <config.h>
  2. #include "proto.h"
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <useconfig.h>
  6. #include "getargs.h"
  7. #include "l2u.h"
  8. #include "hplay.h"
  9. #include "file.h"
  10.  
  11. #define SUN_MAGIC     0x2e736e64        /* Really '.snd' */
  12. #define SUN_HDRSIZE    24            /* Size of minimal header */
  13. #define SUN_UNSPEC    ((unsigned)(~0))    /* Unspecified data size */
  14. #define SUN_ULAW    1            /* u-law encoding */
  15. #define SUN_LIN_8    2            /* Linear 8 bits */
  16. #define SUN_LIN_16    3            /* Linear 16 bits */
  17.  
  18. file_write_p file_write = NULL;
  19. file_term_p  file_term  = NULL;
  20.  
  21. static char *linear_file;
  22. static char *au_file;
  23. static char *wav_file;
  24. static int au_fd = -1;            /* file descriptor for .au ulaw file */
  25. static int linear_fd = -1;
  26. static int wav_fd = -1;
  27.  
  28. static unsigned au_encoding = SUN_ULAW;
  29. static unsigned au_size = 0;
  30. static unsigned wav_size = 0;
  31.  
  32. static void wblong PROTO((int fd, unsigned long x));
  33. static void 
  34. wblong(fd, x)
  35. int fd;
  36. unsigned long x;
  37. {
  38.  int i;
  39.  for (i = 24; i >= 0; i -= 8)
  40.   {
  41.    char byte = (char) ((x >> i) & 0xFF);
  42.    write(fd, &byte, 1);
  43.   }
  44. }
  45.  
  46. static void walong PROTO((int fd, unsigned long x));
  47. static void 
  48. walong(fd, x)
  49. int fd;
  50. unsigned long x;
  51. {
  52.  int i;
  53.  for (i = 0; i <= 24; i += 8)
  54.   {
  55.    unsigned char byte = (unsigned char) ((x >> i) & 0xFF);
  56.    write(fd, &byte, 1);
  57.   }
  58. }
  59.  
  60.  
  61. extern void au_header PROTO((int fd,unsigned enc,unsigned rate,unsigned size,char *comment));
  62.  
  63. void 
  64. au_header(fd, enc, rate, size, comment)
  65. int fd;
  66. unsigned enc;
  67. unsigned rate;
  68. unsigned size;
  69. char *comment;
  70. {
  71.  if (!comment)
  72.   comment = "";
  73.  wblong(fd, SUN_MAGIC);
  74.  wblong(fd, SUN_HDRSIZE + strlen(comment));
  75.  wblong(fd, size);
  76.  wblong(fd, enc);
  77.  wblong(fd, rate);
  78.  wblong(fd, 1);                   /* channels */
  79.  write(fd, comment, strlen(comment));
  80. }
  81.  
  82. void WriteWaveHeader(int fh, int n)
  83. {
  84.     long bl;
  85.     int  bi;
  86.  
  87.     write(fh, "RIFF",4);    // Write "RIFF"
  88.     bl  = n + 36;
  89.     walong(fh,bl);             // Write Size of file with header
  90.     write(fh, "WAVE",4);    // Write "WAVE"
  91.     write(fh, "fmt ",4);      // Write "fmt "
  92.     bl = 0x00000010;
  93.     walong(fh,bl);    // Size of previous header (fixed)
  94.     bl = 0x00010001;
  95.     walong(fh, bl);    // formatTag and nChannels
  96.     bl = samp_rate;     
  97.     walong(fh, bl);    // nSamplesPerSec
  98.     bl = samp_rate * (bits + 7)  / 8;
  99.     walong(fh, bl);     // nAvgBytesPerSec
  100.     bl = 0x00080008;
  101.     walong(fh,bl);        // nBlockAlign (always 1?) / nBitsPerSample
  102.     write(fh,"data",4);     // Write "data"
  103.     bl = n;
  104.     walong(fh, bl);    // True length of sample data
  105.     bl = 0;
  106.    walong(fh,bl);
  107. }
  108.  
  109. static void aufile_write PROTO((int n,short *data));
  110.  
  111. static void
  112. aufile_write(n, data)
  113. int n;
  114. short *data;
  115. {
  116.  if (n > 0)
  117.   {
  118.    if (linear_fd >= 0)
  119.     {
  120.      unsigned size = n * sizeof(short);
  121.      if (write(linear_fd, data, n * sizeof(short)) != size)
  122.             perror("write");
  123.     }
  124.    if (au_fd >= 0)
  125.     {
  126.      if (au_encoding == SUN_LIN_16)
  127.       {
  128.        unsigned size = n * sizeof(short);
  129.        if (write(au_fd, data, size) != size)
  130.         perror("write");
  131.        else
  132.         au_size += size;
  133.       }
  134.      else if (au_encoding == SUN_ULAW)
  135.       {
  136.        unsigned char *plabuf = (unsigned char *) malloc(n);
  137.        if (plabuf)
  138.         {
  139.          unsigned char *p = plabuf;
  140.          unsigned char *e = p + n;
  141.          while (p < e)
  142.           {
  143.            *p++ = short2ulaw(*data++);
  144.           }
  145.          if (write(au_fd, plabuf, n) != n)
  146.           perror(au_file);
  147.          else
  148.           au_size += n;
  149.          free(plabuf);
  150.         }
  151.        else
  152.         {
  153.          fprintf(stderr, "%s : No memory for ulaw data\n", program);
  154.         }
  155.       }
  156.      else
  157.       {
  158.        abort();
  159.       }
  160.     }
  161.   }
  162.  if (wav_fd >= 0)
  163.    {
  164.       unsigned char *plabuf = (unsigned char *) malloc(n);
  165.       WriteWaveHeader(wav_fd,n);
  166.       if (plabuf)
  167.        {
  168.           unsigned char *p = plabuf;
  169.           unsigned char *e = p + n;
  170.           while (p < e)
  171.             {
  172.              *data /= 128  ;
  173.              *p = *data + 128;
  174.               p++;
  175.               data++;
  176.             }
  177.           if (write(wav_fd, plabuf, n) != n)
  178.             perror(wav_file);
  179.           else 
  180.             wav_size += n;
  181.           free(plabuf);
  182.         }  
  183.        else
  184.         {
  185.          fprintf(stderr, "%s : No memory for wav data\n", program);
  186.          return;
  187.         }
  188.      }
  189.  }
  190.  
  191.  
  192. static void aufile_term PROTO((void));
  193.  
  194. static void
  195. aufile_term()
  196. {
  197.  /* Finish ulaw file */
  198.  if (au_fd >= 0)
  199.   {
  200.    off_t here = lseek(au_fd, 0L, SEEK_CUR);
  201.    if (here >= 0)
  202.     {
  203.      /* can seek this file - truncate it */
  204.      ftruncate(au_fd, here);
  205.      /* Now go back and overwite header with actual size */
  206.      if (lseek(au_fd, 8L, SEEK_SET) == 8)
  207.       {
  208.        wblong(au_fd, au_size);
  209.       }
  210.     }
  211.    if (au_fd != 1)
  212.     close(au_fd);
  213.    au_fd = -1;
  214.   }
  215.  /* Finish linear file */
  216.  if (linear_fd >= 0)
  217.   {
  218.    ftruncate(linear_fd, lseek(linear_fd, 0L, SEEK_CUR));
  219.    if (linear_fd != 1)
  220.     close(linear_fd);
  221.    linear_fd = -1;
  222.   }
  223. /* finish WAV file */
  224.  if (wav_fd >= 0)
  225.   {
  226.    off_t here = lseek(wav_fd, 0L, SEEK_CUR);
  227.    if (here >= 0)
  228.     {
  229.      /* can seek this file - truncate it */
  230.      ftruncate(wav_fd, here);
  231.      /* Now go back and overwite header with actual size */
  232.      if (lseek(wav_fd, 4L, SEEK_SET) == 4)
  233.       {
  234.        walong(wav_fd, wav_size+36);
  235.       }
  236.      if (lseek(wav_fd, 40L, SEEK_SET) == 40)
  237.       {
  238.        walong(wav_fd, wav_size);
  239.       }
  240.  
  241.     }
  242.    if (wav_fd != 1)
  243.     close(wav_fd);
  244.    wav_fd = -1;
  245.   }
  246.  
  247. }
  248.  
  249.  
  250. int
  251. file_init(argc, argv)
  252. int argc;
  253. char *argv[];
  254. {
  255.  argc = getargs("File output", argc, argv,
  256.                 "l", "", &linear_file, "Raw 16-bit linear pathname",
  257.                 "o", "", &au_file,     "Sun/Next audio file name",
  258.                 "w", "", &wav_file,    "OS/2 WAV File name",
  259.                 NULL);
  260.  if (help_only)
  261.   return argc;
  262.  
  263.  if (au_file)
  264.   {
  265.    if (strcmp(au_file, "-") == 0)
  266.     {
  267.      au_fd = 1;                   /* stdout */
  268.     }
  269.    else
  270.     {
  271.      au_fd = open(au_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  272.      if (au_fd < 0)
  273.       perror(au_file);
  274.     }
  275.    if (au_fd >= 0)
  276.     {
  277.      if (samp_rate > 8000)
  278.       au_encoding = SUN_LIN_16;
  279.      else
  280.       au_encoding = SUN_ULAW;
  281.      au_header(au_fd, au_encoding, samp_rate, SUN_UNSPEC, "");
  282.      au_size = 0;
  283.     }
  284.   }
  285.  
  286.  if (linear_file)
  287.   {
  288.    if (strcmp(linear_file, "-") == 0)
  289.     {
  290.      linear_fd = 1 /* stdout */ ;
  291.     }
  292.    else
  293.     {
  294.      linear_fd = open(linear_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  295.      if (linear_fd < 0)
  296.       perror(linear_file);
  297.     }
  298.   }
  299.  if (wav_file)
  300.   {
  301.    if (strcmp(wav_file, "-") == 0)
  302.     {
  303.      wav_fd = 1 /* stdout */ ;
  304.     }
  305.    else
  306.     {
  307.      wav_fd = open(wav_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
  308.      if (wav_fd < 0)
  309.       perror(wav_file);
  310.     }
  311.   }
  312.  
  313.  
  314.  if (au_fd >= 0 || linear_fd >= 0 || wav_fd > 0)
  315.   {
  316.    file_write = aufile_write;
  317.    file_term  = aufile_term;
  318.   }
  319.  return argc;
  320. }
  321.  
  322.  
  323.